﻿#region Copyright (c) 2000-2011 Developer Express Inc.
/*
{*******************************************************************}
{                                                                   }
{       Developer Express .NET Component Library                    }
{                                                                   }
{                                                                   }
{       Copyright (c) 2000-2011 Developer Express Inc.              }
{       ALL RIGHTS RESERVED                                         }
{                                                                   }
{   The entire contents of this file is protected by U.S. and       }
{   International Copyright Laws. Unauthorized reproduction,        }
{   reverse-engineering, and distribution of all or any portion of  }
{   the code contained in this file is strictly prohibited and may  }
{   result in severe civil and criminal penalties and will be       }
{   prosecuted to the maximum extent possible under the law.        }
{                                                                   }
{   RESTRICTIONS                                                    }
{                                                                   }
{   THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES           }
{   ARE CONFIDENTIAL AND PROPRIETARY TRADE                          }
{   SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS   }
{   LICENSED TO DISTRIBUTE THE PRODUCT AND ALL ACCOMPANYING .NET    }
{   CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY.                 }
{                                                                   }
{   THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED      }
{   FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE        }
{   COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE       }
{   AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT  }
{   AND PERMISSION FROM DEVELOPER EXPRESS INC.                      }
{                                                                   }
{   CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON       }
{   ADDITIONAL RESTRICTIONS.                                        }
{                                                                   }
{*******************************************************************}
*/
#endregion Copyright (c) 2000-2010 Developer Express Inc.

#if TEST
namespace DevExpress.OAuth {
    using System;
    using NUnit.Framework;
    using DevExpress.OAuth.Provider;
    using DevExpress.OAuth.Authentication;
    using System.Net;

    [TestFixture]
    public class Tests {

        [Test]
        public void Spec_10() {
            ServiceProvider serviceProvider = new ServiceProvider();
            ValidationScope scope;

            Consumer consumer = new Consumer();
            consumer.CallbackUri = new Uri("http://tempuri.org/Callback");
            consumer.RequestUri = new Uri("http://tempuri.org/GetRequestToken");
            consumer.AuthorizeUri = new Uri("http://tempuri.org/Authorize");
            consumer.AccessUri = new Uri("http://tempuri.org/GetAccessToken");
            consumer.Signature = Signature.HMACSHA1;
            consumer.ConsumerKey = "anonymous";
            consumer.ConsumerSecret = "anonymous";
            
            /* 
             * GetRequestToken (Client-side)
             */
            
            consumer.GetRequestToken(serviceProvider);
            Assert.IsNotNull(consumer.RequestToken);
            Assert.AreEqual(consumer.ConsumerKey, consumer.RequestToken.ConsumerKey);
            Assert.AreEqual(consumer.ConsumerSecret, consumer.RequestToken.ConsumerSecret);
            Assert.AreEqual(consumer.CallbackUri.ToString(), consumer.RequestToken.Callback);
            Assert.IsNullOrEmpty(consumer.RequestToken.Verifier);

            /* 
             * AuthorizeToken (Server-side)
             */

            IToken verifiedToken = ServiceProvider.VerifyRequestToken(
                consumer.HttpMethod,
                consumer.GetAuthorizeTokenUrl(consumer.RequestToken),
                out scope);
            if (scope != null) {
                foreach (ValidationError error in scope.Errors) {
                    Assert.Fail(error.Message);
                }
            }
            Assert.IsNotNull(verifiedToken);
            Assert.AreEqual(consumer.RequestToken.ConsumerKey, verifiedToken.ConsumerKey);
            Assert.AreEqual(consumer.RequestToken.ConsumerSecret, verifiedToken.ConsumerSecret);
            Assert.AreEqual(consumer.RequestToken.Callback, verifiedToken.Callback);
            Assert.AreEqual(consumer.RequestToken.Value, verifiedToken.Value);
            Assert.AreEqual(consumer.RequestToken.Secret, verifiedToken.Secret);
            Assert.IsNotNullOrEmpty(verifiedToken.Verifier);

            IToken authorizedToken = ServiceProvider.AuthorizeRequestToken(
                consumer.HttpMethod,
                consumer.GetAuthorizeTokenUrl(consumer.RequestToken),
                "John Doe",
                out scope);
            if (scope != null) {
                foreach (ValidationError error in scope.Errors) {
                    Assert.Fail(error.Message);
                }
            }

            Assert.IsNotNull(authorizedToken);
            Assert.AreEqual(verifiedToken.ConsumerKey, authorizedToken.ConsumerKey);
            Assert.AreEqual(verifiedToken.ConsumerSecret, authorizedToken.ConsumerSecret);
            Assert.AreEqual(verifiedToken.Callback, authorizedToken.Callback);
            Assert.AreEqual(verifiedToken.Value, authorizedToken.Value);
            Assert.AreEqual(verifiedToken.Secret, authorizedToken.Secret);
            Assert.IsNotNullOrEmpty(authorizedToken.Verifier);
            Assert.AreEqual(verifiedToken.Verifier, authorizedToken.Verifier);
            Assert.AreEqual("John Doe", authorizedToken.AuthenticationTicket);

            /* 
             * GetAccessToken
             */

            consumer.GetAccessToken(
               serviceProvider,
               consumer.RequestToken,
               authorizedToken.Verifier);

            Assert.IsNotNull(consumer.AccessToken);
            Assert.AreEqual(consumer.ConsumerKey, consumer.AccessToken.ConsumerKey);
            Assert.AreEqual(consumer.ConsumerSecret, consumer.AccessToken.ConsumerSecret);
            Assert.AreEqual(consumer.CallbackUri.ToString(), consumer.AccessToken.Callback);

            /* GetTokenIdentity */

            TokenIdentity identity = ServiceProvider.GetTokenIdentity(
                serviceProvider,
                consumer.HttpMethod,
                new Uri("http://tempuri.org/Resoure"),
                "Basic",
                out scope);

            Assert.IsNull(identity);
            Assert.IsNull(scope);

            HttpWebRequest request = Consumer.GetRequest10(
                new Uri("http://tempuri.org/Resoure"),
                consumer.AccessToken,
                consumer.HttpMethod,
                consumer.ConsumerKey,
                consumer.ConsumerSecret,
                consumer.Signature,
                String.Empty,
                consumer.Cookies);

            identity = ServiceProvider.GetTokenIdentity(
                serviceProvider,
                request.Method,
                request.RequestUri,
                request.Headers[HttpRequestHeader.Authorization],
                out scope);
            Assert.IsNotNull(identity);
            Assert.IsNull(scope);
            Assert.AreEqual(consumer.AccessToken.Value, identity.Token);
            Assert.AreEqual("John Doe", identity.AuthenticationTicket);

        }

        [Test]
        public void Parsing() {
            OAuth.Parameter para = new OAuth.Parameter();
            Assert.IsTrue(para.IsEmpty);
            Assert.AreEqual("", para.Name);
            Assert.AreEqual("", para.Value);

            para = new OAuth.Parameter("oauth_nonce", null);
            Assert.IsFalse(para.IsEmpty);
            Assert.AreEqual("oauth_nonce", para.Name);
            Assert.AreEqual("", para.Value);

            para = new OAuth.Parameter("oauth_nonce", "0123456789ABCDE");
            Assert.IsFalse(para.IsEmpty);
            Assert.AreEqual("oauth_nonce", para.Name);
            Assert.AreEqual("0123456789ABCDE", para.Value);

            para = OAuth.Parameter.Parse("oauth_signature=");
            Assert.AreEqual("oauth_signature", para.Name);
            Assert.AreEqual("", para.Value);

            para = OAuth.Parameter.Parse("oauth_signature");
            Assert.AreEqual("oauth_signature", para.Name);
            Assert.AreEqual("", para.Value);

            para = OAuth.Parameter.Parse("oauth_signature=");
            Assert.AreEqual("oauth_signature", para.Name);
            Assert.AreEqual("", para.Value);

            Assert.Catch<FormatException>(() => { OAuth.Parameter.Parse("=oauth_signature"); });

            para = OAuth.Parameter.Parse("http://example.net");
            Assert.AreEqual("http://example.net", para.Name);

            para = OAuth.Parameter.Parse("url=http://example.net");
            Assert.AreEqual("url", para.Name);
            Assert.AreEqual("http://example.net", para.Value);

            para = OAuth.Parameter.Parse("url=  http://example.net  ");
            Assert.AreEqual("url", para.Name);
            Assert.AreEqual("http://example.net", para.Value);

            para = OAuth.Parameter.Parse("url=    ");
            Assert.AreEqual("url", para.Name);
            Assert.AreEqual(String.Empty, para.Value);

            para = OAuth.Parameter.Parse("url=    value");
            Assert.AreEqual("url", para.Name);
            Assert.AreEqual("value", para.Value);

            para = OAuth.Parameter.Parse("url=value    ");
            Assert.AreEqual("url", para.Name);
            Assert.AreEqual("value", para.Value);

            para = OAuth.Parameter.Parse("url=\"", true, true);
            Assert.AreEqual("url", para.Name);
            Assert.AreEqual("\"", para.Value);

            para = OAuth.Parameter.Parse("url=\"\"", true, true);
            Assert.AreEqual("url", para.Name);
            Assert.AreEqual("", para.Value);

            para = OAuth.Parameter.Parse("url=\"value\"");
            Assert.AreEqual("url", para.Name);
            Assert.AreEqual("\"value\"", para.Value);

            para = OAuth.Parameter.Parse("url=  \"  value  \"  ", true, true);
            Assert.AreEqual("url", para.Name);
            Assert.AreEqual("  value  ", para.Value);

            para = OAuth.Parameter.Parse("url=  \"  \"  ", true, true);
            Assert.AreEqual("url", para.Name);
            Assert.AreEqual("  ", para.Value);

            para = OAuth.Parameter.Parse("oauth_signature=tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D");
            Assert.AreEqual("oauth_signature", para.Name);
            Assert.AreEqual("tR3+Ty81lMeYAr/Fid0kMTYa/WM=", para.Value);

            para = OAuth.Parameter.Parse("callback=https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthGetRequestToken");
            Assert.AreEqual("callback", para.Name);
            Assert.AreEqual("https://www.google.com/accounts/OAuthGetRequestToken", para.Value);

            OAuth.Parameters paras = OAuth.Parameters.ParseTokens("oauth_signature=tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D");
            Assert.AreEqual(1, paras.Count);
            Assert.AreEqual("oauth_signature", paras[0].Name);
            Assert.AreEqual("tR3+Ty81lMeYAr/Fid0kMTYa/WM=", paras[0].Value);

            paras = OAuth.Parameters.ParseTokens("&");
            Assert.AreEqual(2, paras.Count);
            Assert.AreEqual("", paras[0].Name);
            Assert.AreEqual("", paras[0].Value);
            Assert.AreEqual("", paras[1].Name);
            Assert.AreEqual("", paras[1].Value);

            paras = OAuth.Parameters.ParseTokens("oauth_signature=tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D&");
            Assert.AreEqual(2, paras.Count);
            Assert.AreEqual("oauth_signature", paras[0].Name);
            Assert.AreEqual("tR3+Ty81lMeYAr/Fid0kMTYa/WM=", paras[0].Value);
            Assert.AreEqual("", paras[1].Name);
            Assert.AreEqual("", paras[1].Value);

            paras = OAuth.Parameters.ParseTokens("oauth_signature=tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D&oauth_nonce=0123456789ABCDE");
            Assert.AreEqual(2, paras.Count);
            Assert.AreEqual("oauth_signature", paras[0].Name);
            Assert.AreEqual("tR3+Ty81lMeYAr/Fid0kMTYa/WM=", paras[0].Value);
            Assert.AreEqual("oauth_nonce", paras[1].Name);
            Assert.AreEqual("0123456789ABCDE", paras[1].Value);
        }

        [Test]
        public void Rfc5849_34131() {
            /* 
             * http://tools.ietf.org/html/rfc5849#section-3 : 
             * 3.4.1.3.1.  Parameter Sources
             */
            
            Parameters p = Parameters.FromUri(
                new Uri("http://tempuri.org/request?b5=%3D%253D&a3=a&c%40=&a2=r%20b"),
                @"OAuth realm=""Example"",
                      oauth_consumer_key=""9djdj82h48djs9d2"",
                      oauth_token=""kkk9d7dh3k39sjv7"",
                      oauth_signature_method=""HMAC-SHA1"",
                      oauth_timestamp=""137131201"",
                      oauth_nonce=""7d8f3e4a"",
                      oauth_signature=""djosJKDKJSD8743243%2Fjdk33klY%3D""");
               
            /*
               +------------------------+------------------+
               |          Name          |       Value      |
               +------------------------+------------------+
               |           b5           |       =%3D       |
               |           a3           |         a        |
               |           c@           |                  |
               |           a2           |        r b       |
               |   oauth_consumer_key   | 9djdj82h48djs9d2 |
               |       oauth_token      | kkk9d7dh3k39sjv7 |
               | oauth_signature_method |     HMAC-SHA1    |
               |     oauth_timestamp    |     137131201    |
               |       oauth_nonce      |     7d8f3e4a     |
               |           c2           |                  |
               |           a3           |        2 q       |
               +------------------------+------------------+
            */

            Assert.AreEqual("=%3D", p["b5"].Value);
            Assert.AreEqual("a", p["a3"].Value);
            Assert.AreEqual(String.Empty, p["c@"].Value);
            Assert.AreEqual("9djdj82h48djs9d2", p["oauth_consumer_key"].Value);
            Assert.AreEqual("kkk9d7dh3k39sjv7", p["oauth_token"].Value);
            Assert.AreEqual("HMAC-SHA1", p["oauth_signature_method"].Value);
            Assert.AreEqual("137131201", p["oauth_timestamp"].Value);
            Assert.AreEqual("7d8f3e4a", p["oauth_nonce"].Value);

        }

        [Test]
        public void Rfc3986() {
            Assert.AreEqual("abc=", DevExpress.OAuth.Escaping.Unescape(":::abc%3D", 3, 6));
            Assert.AreEqual("tR3+Ty81lMeYAr/Fid0kMTYa/WM=", DevExpress.OAuth.Escaping.Unescape("tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D"));
            Assert.AreEqual("https://www.google.com/accounts/OAuthGetRequestToken", DevExpress.OAuth.Escaping.Unescape("https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthGetRequestToken"));
        }

        [Test]
        public void HmaSha1_2() {
            
            Parameter[] authParams = new Parameter[] { 
               new Parameter("oauth_consumer_key", "anonymous"),
               new Parameter("oauth_signature_method", "HMAC-SHA1"), 
               new Parameter("oauth_timestamp", "1297298895"),
               new Parameter("oauth_nonce", "dfa3e4e804e0538222d79fb32136e116"),
               new Parameter("oauth_version", "1.0"),
               new Parameter("oauth_callback", "http://googlecodesamples.com/oauth_playground/index.php"),
               new Parameter("scope", "https://www.google.com/calendar/feeds/"),
            };

            const string sigBaseExpected
                = "GET&https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthGetRequestToken&oauth_callback%3Dhttp%253A%252F%252Fgooglecodesamples.com%252Foauth_playground%252Findex.php%26oauth_consumer_key%3Danonymous%26oauth_nonce%3Ddfa3e4e804e0538222d79fb32136e116%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1297298895%26oauth_version%3D1.0%26scope%3Dhttps%253A%252F%252Fwww.google.com%252Fcalendar%252Ffeeds%252F";
            
            string sigBase = Signing.HmaSha1.Base(
                "GET",
                (Url)"https://www.google.com/accounts/OAuthGetRequestToken",
                false,
                authParams);

            Assert.AreEqual(sigBaseExpected, sigBase);

            Parameter sig = Signing.HmaSha1.Sign(sigBase, "anonymous", "");
            
            Assert.AreEqual("oauth_signature", sig.Name);
            Assert.AreEqual("IonZleltpsrsGUoobrgiNYWzBdU%3D", DevExpress.OAuth.Escaping.Escape(sig.Value));

        }

        [Test]
        public void HmaSha1_1() {

            /* See: http://oauth.net/core/1.0/#anchor30 */
            
            Parameter[] authParams = new Parameter[] { 
               new Parameter("oauth_consumer_key", "dpf43f3p2l4k3l03"),  
               new Parameter("oauth_token", "nnch734d00sl2jdk"),  
               new Parameter("oauth_signature_method", "HMAC-SHA1"),  
               new Parameter("oauth_timestamp", "1191242096"),  
               new Parameter("oauth_nonce", "kllo9940pd9333jh"),  
               new Parameter("oauth_version", "1.0"),  
               new Parameter("file", "vacation.jpg"),
               new Parameter("size", "original"),
            };

            const string sigBaseExpected 
                = "GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal";

            string sigBase = Signing.HmaSha1.Base(
                "GET",
                (Url)"http://photos.example.net/photos",
                authParams);

            Assert.AreEqual(sigBaseExpected, sigBase);

            string sigHash = Signing.HmaSha1.Hash(sigBase, "kd94hf93k423kf44&pfkkdhi9sl3r4s00");

            Assert.AreEqual("tR3+Ty81lMeYAr/Fid0kMTYa/WM=", sigHash);

            Parameter sig = Signing.HmaSha1.Sign(sigBase, "kd94hf93k423kf44", "pfkkdhi9sl3r4s00");

            Assert.AreEqual("oauth_signature", sig.Name);
            Assert.AreEqual("tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D", DevExpress.OAuth.Escaping.Escape(sig.Value));

        }

    }
}
#endif